package com.hjb.service.impl.user;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hjb.service.config.constant.Constants;
import com.hjb.service.domain.product.Product;
import com.hjb.service.domain.product.ProductExample;
import com.hjb.service.domain.siteuser.SiteUserAccountLog;
import com.hjb.service.domain.siteuser.SiteUserAddRate;
import com.hjb.service.domain.siteuser.SiteUserAddRateExample;
import com.hjb.service.domain.siteuser.SiteUserExperienceLog;
import com.hjb.service.domain.siteuser.SiteUserProfit;
import com.hjb.service.domain.siteuseraccount.SiteUserAccount;
import com.hjb.service.domain.siteuseraccount.SiteUserAccountExample;
import com.hjb.service.mapper.ProductMapper;
import com.hjb.service.mapper.SiteUserAccountLogMapper;
import com.hjb.service.mapper.SiteUserAccountMapper;
import com.hjb.service.mapper.SiteUserAddRateMapper;
import com.hjb.service.mapper.SiteUserExperienceLogMapper;
import com.hjb.service.mapper.SiteUserProfitMapper;
import com.hjb.service.user.SiteSysAccountService;
import com.hjb.service.user.SiteUserAccountService;
import com.hjb.service.utils.HJBUT;

@Service
public class SiteUserAccountServiceImpl implements SiteUserAccountService {

	private Logger log = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private SiteUserAccountMapper siteUserAccountMapper;
	@Autowired
	private SiteUserAccountLogMapper siteUserAccountLogMapper;
	@Autowired
	private SiteUserExperienceLogMapper userExperienceLogMapper;
	@Autowired
	private ProductMapper productMapper;
	@Autowired
	private SiteUserAddRateMapper siteUserAddRateMapper;
	@Autowired
	private SiteUserProfitMapper siteUserProfitMapper;
	@Autowired
	private SiteSysAccountService siteSysAccountService;

	@Override
	public List<SiteUserAccount> selectByExample(SiteUserAccountExample example) {
		return siteUserAccountMapper.selectByExample(example);
	}

	@Override
	public int insertSiteUserAccount(SiteUserAccount siteUserAccount) {
		return siteUserAccountMapper.insertSelective(siteUserAccount);
	}

	@Override
	public void updateSiteUserAccount(SiteUserAccount siteUserAccount) {
		siteUserAccountMapper.updateByPrimaryKeySelective(siteUserAccount);
	}

	@Override
	public int updateCurrentAccount(Integer userId,BigDecimal amount,int acctType,Integer inAccount,Integer outAccount,
			String orderId,String currnetOrder,String fixedOrder,String desc,String inMsg,String outMsg) {
		Map<String,Object> params = new HashMap<String, Object>();
		params.put("userId", userId);
		params.put("amount", amount);
		int res = siteUserAccountMapper.updateCurrentBalance(params);
		int logStatus = Constants.COMMON_STATUS_3;
		if(res !=1){
			logStatus = Constants.COMMON_STATUS_2;
//			desc +="活期余额扣款失败：余额不足,交易金额："+amount;
			log.info("活期余额扣款失败：余额不足..user_id:"+userId+",交易金额："+amount);
		}
		
		//记录日志
		SiteUserAccountLog userAccountLog = new SiteUserAccountLog();
		userAccountLog.setUserId(userId);
		userAccountLog.setAcctType(acctType);
		userAccountLog.setCreateTime(new Date());
		userAccountLog.setInAccount(inAccount);
		userAccountLog.setOutAccount(outAccount);
		userAccountLog.setAmount(amount);
		userAccountLog.setStatus(logStatus);
		userAccountLog.setOrderId(orderId);
		userAccountLog.setCurrnetOrder(currnetOrder);
		userAccountLog.setFixedOrder(fixedOrder);
		userAccountLog.setInfo(desc);
		userAccountLog.setInMsg(inMsg);
		userAccountLog.setOutMsg(outMsg);
		
		siteUserAccountLogMapper.insertSelective(userAccountLog);
		
		return res;
	}

	@Override
	public int updateFrozenAccount(Integer userId, BigDecimal amount,
			int acctType, Integer inAccount, Integer outAccount,
			String orderId, String currnetOrder, String fixedOrder, String desc) {
		Map<String,Object> params = new HashMap<String, Object>();
		params.put("userId", userId);
		params.put("amount", amount);
		int res = siteUserAccountMapper.updateFrozenAccount(params);
//		int logStatus = Constants.COMMON_STATUS_1;
//		if(res !=1){
//			logStatus = Constants.COMMON_STATUS_2;
//			log.info("冻结余额操作失败..user_id:"+userId+",交易金额："+amount);
//		}
		
		//记录日志
//		SiteUserAccountLog userAccountLog = new SiteUserAccountLog();
//		userAccountLog.setUserId(userId);
//		userAccountLog.setAcctType(acctType);
//		userAccountLog.setCreateTime(new Date());
//		userAccountLog.setInAccount(inAccount);
//		userAccountLog.setOutAccount(outAccount);
//		userAccountLog.setAmount(amount);
//		userAccountLog.setStatus(logStatus);
//		userAccountLog.setOrderId(orderId);
//		userAccountLog.setCurrnetOrder(currnetOrder);
//		userAccountLog.setFixedOrder(fixedOrder);
//		userAccountLog.setInfo(desc);
//		
//		siteUserAccountLogMapper.insertSelective(userAccountLog);
		
		return res;
	}

	@Override
	public int updateExperienceAccount(Integer userId, BigDecimal amount,
			int type, Integer inAccount, Integer outAccount, String desc) {
		log.info("体验金账户：user_id:"+userId+",操作金额："+amount+",描述："+desc);
		
		BigDecimal updateAmount = amount;
		if(type ==1){
			updateAmount = amount.negate();
		}
		Map<String,Object> params = new HashMap<String, Object>();
		params.put("userId", userId);
		params.put("amount", updateAmount);
		int res = siteUserAccountMapper.updateExperienceAccount(params);
		
		SiteUserExperienceLog experienceLog = new SiteUserExperienceLog();
		experienceLog.setUserId(userId);
		experienceLog.setAmount(amount);
		experienceLog.setType(type);
		experienceLog.setRemark(desc);
		experienceLog.setCreateTime(HJBUT.currentTime());
		
		userExperienceLogMapper.insertSelective(experienceLog);
		
		return res;
	}

	@Override
	@Transactional
	public void settlementCurrentIncome() {
		try {
			log.info("活期收益结算任务开始：.....................:"+HJBUT.currentTime());
			//查询活期产品详情
			ProductExample productExample = new ProductExample();
			productExample.createCriteria().andTypeEqualTo(Constants.PRODUCT_TYPE_1).andStautsNotEqualTo(Constants.COMMON_STATUS_2);
			List<Product> productList = productMapper.selectByExample(productExample);
			if(productList.size()<1){
				log.info("活期收益结算任务未查询到产品信息：.....................:"+HJBUT.currentTime());
				return;
			}
			Product product = productList.get(0);
			
			//查询活期持有金额大于0的账户列表
			SiteUserAccountExample userAccountExample = new SiteUserAccountExample();
			userAccountExample.createCriteria().andCurrentAccountGreaterThan(BigDecimal.ZERO);
			List<SiteUserAccount> userAccountList = siteUserAccountMapper.selectByExample(userAccountExample);
			log.info("活期收益结算任务数："+userAccountList.size());
			for(SiteUserAccount userAccount : userAccountList){
				log.info("活期收益结算任务详情：user_id:"+userAccount.getUserId()+",持有活期金额："+userAccount.getCurrentAccount()+",活期产品利率："+product.getRate());
				BigDecimal rate = product.getRate();
				//加息券加息
				BigDecimal addRate = BigDecimal.ZERO;
				//项目加息
				if(product.getAddRate() != null){
					rate = rate.add(product.getAddRate());
				}
				//活期收益
				BigDecimal profit = HJBUT.getInterest(userAccount.getCurrentAccount(),product.getRate(), 1);
				//加息收益
				BigDecimal addProfit = BigDecimal.ZERO;
				SiteUserAddRate userAddRate = null;
				//查询用户加息计划
				SiteUserAddRateExample userAddRateExample = new SiteUserAddRateExample();
				userAddRateExample.createCriteria().andUserIdEqualTo(userAccount.getUserId()).andStatusEqualTo(Constants.COMMON_STATUS_0)
				.andStartDateLessThanOrEqualTo(HJBUT.currentDate()).andEndDateGreaterThanOrEqualTo(HJBUT.currentDate());
				List<SiteUserAddRate> userAddRateList = siteUserAddRateMapper.selectByExample(userAddRateExample); 
				if(userAddRateList.size()> 0){
					userAddRate = userAddRateList.get(0);
				}
				if(userAddRate != null && userAddRate.getAddRate().compareTo(BigDecimal.ZERO) >0){
					addRate = userAddRate.getAddRate();
					addProfit = HJBUT.getInterest(userAccount.getCurrentAccount(), userAddRate.getAddRate(),1);
				}
				//总计收益
				BigDecimal totalProfit = profit.add(addProfit);
				
				//保存收益明细
				SiteUserProfit userProfit = new SiteUserProfit();
				userProfit.setUserId(userAccount.getUserId());
				userProfit.setAmount(totalProfit);
				userProfit.setCurrentAccount(userAccount.getCurrentAccount());
				userProfit.setTotalAmount(userAccount.getTotalCurrentIncome().add(profit));
				userProfit.setRate(rate.add(addRate));
				userProfit.setReturnDate(HJBUT.currentDate());
				userProfit.setCreateTime(HJBUT.currentTime());
				siteUserProfitMapper.insertSelective(userProfit);
				
				//更新用户总账信息
				Map<String,Object> params = new HashMap<String, Object>();
				params.put("userId", userAccount.getUserId());
				params.put("totalAmount", totalProfit);
				params.put("amount", profit);
				params.put("addAmount", addProfit);
				siteUserAccountMapper.updateCurrentAccountByUserId(params);
				
				String desc = "活期收益结算任务详情：user_id:"+userAccount.getUserId()+",持有活期金额："+userAccount.getCurrentAccount()+
						",活期产品利率："+product.getRate()+",收益:"+profit+",加息券收益:"+addProfit;
				
				String inMsg = "活期收益:"+profit;
				
				//系统账户记账，发放活期收益
				siteSysAccountService.updateBanlanceByUserId(Constants.SYS_ACCOUNT_10005, profit, BigDecimal.ZERO, Constants.ACCOUNT_LOG_TYPE_7, 
						userAccount.getUserId(), Constants.SYS_ACCOUNT_10005,
						"", "", "", desc, inMsg, inMsg);
				
				//加息券收益大于0，营销账户记账
				if(addProfit.compareTo(BigDecimal.ZERO) > 0){
					inMsg = "活期加息券收益:"+addProfit;
					//系统账户记账，发放活期收益
					siteSysAccountService.updateBanlanceByUserId(Constants.SYS_ACCOUNT_10006, addProfit, BigDecimal.ZERO, Constants.ACCOUNT_LOG_TYPE_8, 
							userAccount.getUserId(), Constants.SYS_ACCOUNT_10006,
							"", "", "", desc, inMsg, inMsg);
				}
				
			}
			
			log.info("活期收益结算任务结束：.....................:"+HJBUT.currentTime());
		} catch (Exception e) {
			log.info("活期收益结算任务结束异常：.....................:"+HJBUT.currentTime()+e.getMessage());
		}
	}

}
